#ifndef H_ITEMDATABASE
#define H_ITEMDATABASE
#include "precompiled.h"
#include "item.h"
#if !defined(NDEBUG)
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
#endif
namespace weo
{
    namespace engine
    {
        namespace item
        {		
            class Itemdatabase
            {
            private:
                typedef boost::multi_index_container<
                    Item,
                    boost::multi_index::indexed_by<
                    boost::multi_index::ordered_unique<
                    BOOST_MULTI_INDEX_CONST_MEM_FUN(Item,unsigned int,Id)>,
                    boost::multi_index::hashed_non_unique<
                    BOOST_MULTI_INDEX_CONST_MEM_FUN(Item,std::string,Name)>
                    ,
                    boost::multi_index::ordered_non_unique<
                    boost::multi_index::composite_key<
                    Item,
                    BOOST_MULTI_INDEX_CONST_MEM_FUN(Item,unsigned char,Type),
                    BOOST_MULTI_INDEX_CONST_MEM_FUN(Item,unsigned char,Slot),
                    BOOST_MULTI_INDEX_CONST_MEM_FUN(Item,unsigned char,Subtype)
                    >
                    >
                    >
                > Itemdbcontainer;
                Itemdbcontainer m_ItemDB;
                friend class boost::serialization::access;
                template<class Archive>
                void serialize(Archive & ar, const unsigned int /* file_version */)
                {
                    ar & boost::serialization::make_nvp("ItemDB",m_ItemDB);
                }
                static Itemdatabase* s_Itemdatabase;
                unsigned int m_MaxLevel;
                unsigned int m_MinLevel;
                std::vector<std::string> m_AreaVector;
            public:
                Itemdatabase();
                const std::vector<Item> getbyName(std::string name) const ;
                const std::vector<const Item*> getPtrbyName(std::string name) const ;
                const Item getbyId(unsigned int id) const;
                const Item* getPtrbyId(unsigned int id) const;
                const std::vector<Item> getbyType(int type, int slot=0, int subtype=0)  const;
                const std::vector<const Item*> getPtrbyType(int type, int slot=0, int subtype=0)  const;
                void createStaticData();
                unsigned int getMaxLevel() const {return m_MaxLevel;};
                unsigned int getMinLevel() const {return m_MinLevel;};
                std::map<unsigned int, bool>  getAllItemsMap() const;
                const std::vector<std::string>* getAreaVector() const {return &m_AreaVector;};
                void setItem(const Item &item);
                void SaveDB(const std::string file_name)const
                {
                    boost::iostreams::filtering_ostream out;
                    out.push(boost::iostreams::bzip2_compressor());
                    out.push(boost::iostreams::file_descriptor_sink(file_name.c_str()));
                    boost::archive::xml_oarchive oa(out);
                    oa<<boost::serialization::make_nvp("ItemDB",*this);
                }
                void SaveNew() const;
                bool LoadNew();
                bool LoadOverride();
                bool SaveOverride();
                bool LoadDB(const std::string file_name)
                {
                    boost::iostreams::filtering_istream in;
                    try
                    {
                        in.push(boost::iostreams::bzip2_decompressor());
                        in.push(boost::iostreams::file_descriptor_source(file_name.c_str()));
                    }
                    catch(boost::iostreams::filtering_istream::failure e)
                    {
                        std::cout << "Error while loading file" << std::endl;
                        return false;
                    }
                    boost::archive::xml_iarchive ia(in);
                    ia>>boost::serialization::make_nvp("ItemDB",*this);
                    //SaveOverride();
                    LoadOverride();
                    createStaticData();
                    return true;
                }
                void fixAllowed();
                static Itemdatabase* getInstance();
            };		
        };
    };
};
#endif